#ifndef GRAPH_H
#define GRAPH_H

#include "GraphNode.h"
#include "GraphEdge.h"
#include "MazeTypes.h"
#include <vector>
#include <map>
#include <list>
#include <deque>
#include <set>

//typedef std::vector<GraphNode> GraphNodes;
//typedef std::list<GraphEdge> Edges;
//typedef std::vector<EdgeList> EdgeLists;

//typedef std::map<int, GraphNode> NodeMap;
//typedef std::map<int, Edges> EdgeMap;

//typedef std::vector<GraphEdge> EdgeList;

typedef std::deque<int> Trail;

typedef std::vector<GraphNode> Nodes;
//typedef std::vector<EdgeList> Edges;

//struct GNCompare
//{
//	bool operator() (const GraphNode& gn1, const GraphNode& gn2)
//	{
//		return gn1.GetID() < gn2.GetID();
//	}
//};

typedef std::vector<GraphEdge> EdgeSet;

typedef std::vector<GraphEdge> Edges;

class Graph
{
public:
	Graph();
	//Graph();// : m_nextId(0)
	bool IsEmpty() const;

	void AddNode(const GraphNode& node);
	//void AddEdge(GraphEdge& edge);
	//void RemoveNode(const GraphNode& node);

	const GraphNode& GetNode(CellPosition id) const;
	const GraphEdge& GetEdge(CellPosition start, int end) const;
	//const Edges& GetEdgeList(int id) const;
	bool IsEdgePresent(int start, int end) const;
	
	int GetNumNodes() const;
	int GetNumActiveNodes() const;
	int GetNumEdges() const;

	void AddEdge(const GraphEdge& graphEdge);
	Nodes& GetNodes() {return m_nodes;}
	EdgeSet& GetEdges() {return m_edgeSet;}
	GraphEdge& GetEdge(CellPosition start, CellPosition end);

	bool CheckEdge(CellPosition start, CellPosition end);

	Edges GetEdgeList(CellPosition startNode);

	float CalcHeuristic(CellPosition start, CellPosition end);

private:
	//GraphNodes m_nodes;
	//EdgeLists m_edges;

	Nodes m_nodes;
	//Edges m_edges;

	

	Trail m_trail;

	CellPosition m_nextId;

	Edges m_edges;
	EdgeSet m_edgeSet;
};

#endif GRAPH_H